package tech.shupi.babytaptv

import android.content.Context
import tech.shupi.babytaptv.database.CardEntity
import tech.shupi.babytaptv.database.CardRoomDatabase
import com.facebook.react.bridge.*
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.modules.core.DeviceEventManagerModule
import kotlinx.coroutines.*
import java.text.SimpleDateFormat
import java.util.*

class DatabaseModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

    override fun getName(): String = "DatabaseModule"

    private val databaseScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private val database: CardRoomDatabase by lazy {
        CardRoomDatabase.getDatabase(reactApplicationContext)
    }
    
    private val fileAccessService: FileAccessService by lazy {
        FileAccessService(reactApplicationContext)
    }

    @ReactMethod
    fun saveCard(cardData: ReadableMap, serverInfo: ReadableMap?, promise: Promise) {
        databaseScope.launch {
            try {
                val title = cardData.getString("title") ?: ""
                val frontImageUrl = cardData.getString("front_image") ?: ""
                val backText = cardData.getString("back_text") ?: ""
                val audioPath = cardData.getString("audio_path") ?: ""
                val uuid = cardData.getString("uuid") ?: ""
                val createdAt = cardData.getString("created_at") ?: getCurrentTimestamp()
                val updatedAt = cardData.getString("updated_at") ?: getCurrentTimestamp()
                
                // Check if card already exists by UUID
                val existingCard = if (uuid.isNotEmpty()) {
                    database.cardDao().getCardByUuid(cardUuid = uuid)
                } else {
                    null
                }

                // 下载图片和音频文件
                val serverUrl = serverInfo?.getString("url") ?: ""
                var localImagePath = frontImageUrl
                var localAudioPath = audioPath
                
                if (serverUrl.isNotEmpty()) {
                    // 下载图片
                    if (frontImageUrl.isNotEmpty()) {
                        val imageFileName = frontImageUrl.substringAfterLast("/")
                        val localImageFileName = "images/$imageFileName"
                        localImagePath = localImageFileName
                        
                        android.util.Log.d("DatabaseModule", "📥 开始下载图片: $frontImageUrl -> $localImageFileName")
                        val imageDownloaded = downloadFile("$serverUrl/api/images/$frontImageUrl", localImageFileName)
                        if (imageDownloaded) {
                            android.util.Log.d("DatabaseModule", "✅ 图片下载成功: $localImageFileName")
                        } else {
                            android.util.Log.e("DatabaseModule", "❌ 图片下载失败: $frontImageUrl")
                        }
                    }
                    
                    // 下载音频
                    if (audioPath.isNotEmpty()) {
                        val audioFileName = audioPath.substringAfterLast("/")
                        val localAudioFileName = "audio/$audioFileName"
                        localAudioPath = localAudioFileName
                        
                        android.util.Log.d("DatabaseModule", "📥 开始下载音频: $audioPath -> $localAudioFileName")
                        val audioDownloaded = downloadFile("$serverUrl/api/audio/$audioPath", localAudioFileName)
                        if (audioDownloaded) {
                            android.util.Log.d("DatabaseModule", "✅ 音频下载成功: $localAudioFileName")
                        } else {
                            android.util.Log.e("DatabaseModule", "❌ 音频下载失败: $audioPath")
                        }
                    }
                }

                if (existingCard != null) {
                    // Update existing card
                    val updatedCard = existingCard.copy(
                        title = title,
                        front_image = localImagePath,
                        back_text = backText,
                        audio_path = localAudioPath,
                        updated_at = updatedAt
                    )

                    database.cardDao().updateCard(updatedCard)
                    
                    val result = Arguments.createMap().apply {
                        putInt("id", updatedCard.id)
                        putString("message", "卡片更新成功")
                    }
                    
                    promise.resolve(result)
                    sendEvent("onCardSaved", result)
                } else {
                    // Insert new card
                    val card = CardEntity(
                        title = title,
                        front_image = localImagePath,
                        back_text = backText,
                        audio_path = localAudioPath,
                        uuid = uuid,
                        created_at = createdAt,
                        updated_at = updatedAt
                    )

                    val id = database.cardDao().insertCard(card)
                
                    val result = Arguments.createMap().apply {
                        putInt("id", id.toInt())
                        putString("message", "卡片保存成功")
                    }
                    
                    promise.resolve(result)
                    sendEvent("onCardSaved", result)
                }
                
            } catch (e: Exception) {
                promise.reject("DATABASE_ERROR", "保存卡片失败: ${e.message}")
            }
        }
    }

    /**
     * 下载文件到本地
     */
    private suspend fun downloadFile(remoteUrl: String, localPath: String): Boolean {
        return withContext(Dispatchers.IO) {
            try {
                val deferred = CompletableDeferred<Boolean>()
                
                fileAccessService.downloadFile(remoteUrl, localPath) { success, error ->
                    if (success) {
                        deferred.complete(true)
                    } else {
                        android.util.Log.e("DatabaseModule", "下载文件失败: $error")
                        deferred.complete(false)
                    }
                }
                
                deferred.await()
            } catch (e: Exception) {
                android.util.Log.e("DatabaseModule", "下载文件异常", e)
                false
            }
        }
    }

    @ReactMethod
    fun getLocalCards(promise: Promise) {
        databaseScope.launch {
            try {
                val cards = database.cardDao().getAllCards()
                val cardArray = Arguments.createArray()
                
                cards.forEach { cardEntity ->
                    val cardMap = Arguments.createMap().apply {
                        putInt("id", cardEntity.id)
                        putString("title", cardEntity.title)
                        putString("front_image", cardEntity.front_image)
                        putString("back_text", cardEntity.back_text)
                        putString("audio_path", cardEntity.audio_path)
                        putString("uuid", cardEntity.uuid)
                        putString("created_at", cardEntity.created_at)
                        putString("updated_at", cardEntity.updated_at)
                    }
                    cardArray.pushMap(cardMap)
                }
                
                promise.resolve(cardArray)
                
            } catch (e: Exception) {
                promise.reject("DATABASE_ERROR", "获取本地卡片失败: ${e.message}")
            }
        }
    }

    @ReactMethod
    fun deleteCard(cardId: Int, promise: Promise) {
        databaseScope.launch {
            try {
                // 获取卡片信息
                val card = database.cardDao().getCardById(cardId)
                if (card != null) {
                    // 删除关联的文件
                    if (card.front_image.startsWith("images/")) {
                        fileAccessService.deleteFile(card.front_image)
                        android.util.Log.d("DatabaseModule", "🗑️ 删除图片文件: ${card.front_image}")
                    }
                    if (card.audio_path.startsWith("audio/")) {
                        fileAccessService.deleteFile(card.audio_path)
                        android.util.Log.d("DatabaseModule", "🗑️ 删除音频文件: ${card.audio_path}")
                    }
                }
                
                val deletedCount = database.cardDao().deleteCardById(cardId = cardId)
                
                val result = Arguments.createMap().apply {
                    putInt("deletedCount", deletedCount)
                    putString("message", if (deletedCount > 0) "卡片删除成功" else "卡片不存在")
                }
                
                promise.resolve(result)
                
                // Send event to React Native
                sendEvent("onCardDeleted", result)
                
            } catch (e: Exception) {
                promise.reject("DATABASE_ERROR", "删除卡片失败: ${e.message}")
            }
        }
    }

    @ReactMethod
    fun getCardCount(promise: Promise) {
        databaseScope.launch {
            try {
                val count = database.cardDao().getCardCount()
                promise.resolve(count)
            } catch (e: Exception) {
                promise.reject("DATABASE_ERROR", "获取卡片数量失败: ${e.message}")
            }
        }
    }

    private fun getCurrentTimestamp(): String {
        val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
        sdf.timeZone = TimeZone.getTimeZone("UTC")
        return sdf.format(Date())
    }

    private fun sendEvent(eventName: String, params: WritableMap?) {
        reactApplicationContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
            .emit(eventName, params)
    }

    override fun onCatalystInstanceDestroy() {
        super.onCatalystInstanceDestroy()
        databaseScope.cancel()
    }
} 